Repository navigation
Fix requirements pin spellings not contesting VEX (#1602) - #1632
Mikola Lysenko (mikolalysenko) wants to merge 5 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
A requirements.txt line that pins the wired release as `===1.2.3`, `==1.2.3.0` or `==v1.2.3` installs the same upstream wheel as `==1.2.3`, but only the canonical spelling contested another lock's Socket wiring. `vex` attested `not_affected` for a project whose `pip install -r requirements.txt` ships the unpatched release. The requirements reader now records any pin that can only select one release (an `==` pin in any valid PEP 440 spelling, or `===`), and the cross-lock contest compares PyPI versions under PEP 440 equality, the way pip resolves the pin. Ranges and wildcards are still not evidence, since what they install depends on the index. Fixes #1602 Assisted-by: Claude Code:claude-opus-5-5
Review follow-ups for the pin-spelling contest: - pip compares a `===X` pin as a string, so it now contests only a wiring of exactly that version string. `===1.16` no longer withholds an attestation for release 1.16.0, which pip can't install from it. - A lock tree that wires the release itself, under another PEP 440 spelling, is no longer counted as a contester of the other lock. - Reuse purl_key::pypi_same_release instead of a second copy of it. Assisted-by: Claude Code:claude-opus-5-5
The repo's lint test requires purl types to be read through Ecosystem::from_purl rather than an inline prefix check. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 1b96ed7. Configure here.
|
Labeled Ready for review (burn-down agent).
Slack announcement not sent this run (the Slack send tool was unavailable). The next run will retry. Generated by Claude Code |
uv 0.13.2 and later refuse the `environments = []` pylock that Pipenv
2026.8.0 writes ("The target environment is not supported by the
lockfile"). setup-uv had no version pin, so the merge-queue
`e2e_vex_build pipenv::` leg started failing with no change on main,
and that dequeued this PR. Pin uv to 0.13.1, as #1639 does. The change
becomes a no-op once #1639 lands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FuB4p2UQANHrpx4dHRwddS
|
The merge queue dequeued this PR because a CI check failed. The failure isn't this PR's.
The PR needs to be re-queued after CI on d72ed0d passes. The push may also have dismissed the earlier approval. Generated by Claude Code |
|
Wenxin Jiang (@Wenxin-Jiang) this changed after your approval (on Besides merges from main, the only new commit is d72ed0d: the CI-only uv pin from #1639 ( If that's fine with you, re-approving Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1602
Summary
A requirements.txt line that pins the wired release as
===1.2.3,==1.2.3.0,==v1.2.3(orsix==1.16for 1.16.0) installs the same upstream wheel as==1.2.3. Before this PR, only the canonical spelling contested another lock's Socket wiring, sovexattestednot_affected(exit 0) for a project whosepip install -r requirements.txtships the unpatched release. Now every one of those spellings withholds the statement withpatched_ref_unattributable, the same way==1.2.3already did.Root cause
The requirements reader (
vex/discover/pypi_other.rs,registry_pin) took evidence only throughutils::requirements::exact_pin. That function rejects===and versions that don't start with a digit, and it returns1.2.3.0verbatim. The cross-lock contest (ResolvedElsewhere::covers) then compared canonical purl strings, so@1.2.3.0never matched@1.2.3.Fix
registry_pinrecords any requirement that can only select one release:==pin in any valid PEP 440 spelling;===pin, recorded with the newResolvedElsewhere::as_spelledflag because pip compares===as a string.ResolvedElsewhere::coverscompares PyPI versions under PEP 440 equality (purl_key::pypi_same_release), except foras_spelledentries. It checks names first, so the PEP 440 parse runs only for pairs with the same name.six@1.16.0while another lock wiressix@1.16would now be counted as a contester.~=1.2.3,==1.2.*) are still not evidence. What they install depends on the index, which the issue also calls a design question.exact_pincomment in the lock inventory says how the two readers differ.The npm, PyPI and gem wrappers don't need changes: this is Rust discovery logic only.
Tests
===X,==X.0,==vX, padded + marker (real CLI, Pipfile.lock wired)e2e_vex_lockfile pipenv::requirements_pin_spellings_contest_the_lock_wiringvexexit 0, atvex_pipenv_pip_common/mod.rs:1385)===,==1.16.0.0,==v1.16.0,==1.16, case/marker/extras/hash) contests;==1.16.1,~=,==1.16.*,===1.16, other name don'tsocket-patch-core vex::discover::pypi_other::tests::issue_1602_requirements_pin_spellings_contest_wiring...::issue_1602_a_tree_wiring_another_spelling_contests_nothingCommands run locally:
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleancargo test -p socket-patch-core --all-features --lib -- vex::discover production_code_classifies_purls: 416 passed on 1b96ed7cargo test --workspace --all-features --no-fail-fast(on 65efed5): 232 test targets ok. The 10 failures are sandbox-only. Nine are read-only-permission / write-failure tests that can't fail when running as root (uid 0):copy_tree::relax_loop_must_not_traverse_symlinked_root("removal cannot succeed under a read-only parent"),vlt_heal::an_unremovable_hidden_lock…,pypi_poetry::wire_write_failure…,pypi_requirements::wire_failure_rolls_back…, 3 inin_process_redirect, 2 inrepair. The tenth,e2e_bun_lockb::binary_shared_bundled_record_hosted_pin_is_managed, failed because the sandbox proxy blocked patches-api.socket.dev. The one real failure, the purl-type lint, is fixed in 1b96ed7./code-review high
Fixed: the wiring exclusion compared strings exactly;
===was read under PEP 440; duplicate helper; the hard-coded version in the e2e case; the staleexact_pincomment.Not fixed, with reasons:
==Xpin also matchesX+localunder PEP 440. That gap already existed before this PR (a canonical==2.1.0never contested a wired2.1.0+cpu). Lock entries resolve exact versions, so folding local labels intocoverswould be wrong for them. It needs a requirements-only rule, which is a separate follow-up.PurlKey.PurlKeykeys maps across every ecosystem, and PyPI is kept spelling-exact there on purpose (pypi_equivalent_purlsexists for this). Changing it would touch much more than this fix needs.===line, so the contest persists. That's correct: pip installs upstream for that line, so the attestation must stay withheld until the user changes it.===now matches only its exact string.https://claude.ai/code/session_01FuB4p2UQANHrpx4dHRwddS
Generated by Claude Code